import datetime
import logging
import queue
import threading
from utils.DBUtil import DBUtil
from script.spider_common_method import save_video, update_comment, get_all_comment
from models import MonitoringTask, MonitoredVideo, MonitoredVideoHistory, Alert
import asyncio
from bilibili_api import video, sync
from utils.CredentialUtil import CredentialConfig
from script.muti_thread import execute_async_task_concurrently


# 更新脚本，拿来爬取更新每个激活了的任务的评论
def update_task():
    session = DBUtil.get_thread_session()
    tasks = session.query(MonitoringTask).filter_by(is_active=True).all()
    bvids = []
    for task in tasks:
        for task_bvid in task.monitored_videos.split(','):
            bvids.append(task_bvid)
    execute_async_task_concurrently(items=bvids, task_function=update_video)


# 增量爬取视频任务
async def update_video(bvid):
    error_message = None
    try:
        if bvid is None or bvid == '':
            return
        session = DBUtil.get_thread_session()
        # 获取数据库里的这条视频数据
        history_video = session.query(MonitoredVideo).filter_by(bvid=bvid).first()

        if history_video is None:
            return

        # 视频存在时
        if history_video is not None:
            # 实例化 Credential 类
            credential = CredentialConfig.get_credential()
            # 实例化 Video 类
            v = video.Video(bvid=bvid, credential=credential)
            # 获取视频信息
            info = await v.get_info()
            # 数据刷入历史数据
            update_video_history_from_now(history_video)
            # 更新数据
            # history_video.bvid = info['bvid']  # 视频bv号
            # history_video.aid = info['aid']  # 视频av号
            # history_video.video_name = info['title']  # 视频标题
            # history_video.tname = info['tname']  # 类别
            # history_video.last_comment_time = history_video.last_comment_time  # 最近评论时间
            # history_video.comment_count = info['stat']['reply']  # 评论数量
            # history_video.violence_count = history_video.violence_count  # 评论
            # history_video.pubdate = datetime.datetime.fromtimestamp(info['pubdate'])  # 视频发布时间
            history_video.views = info['stat']['view']  # 视频浏览量
            history_video.danmaku = info['stat']['danmaku']  # 弹幕条数
            history_video.favorite = info['stat']['favorite']  # 收藏数量
            history_video.coin = info['stat']['coin']  # 投币数
            history_video.share = info['stat']['share']  # 分享数
            history_video.like = info['stat']['like']  # 点赞数
            history_video.dislike = info['stat']['dislike']  # 点踩数量
            # history_video.duration = info['duration']  # 视频时长
            history_video.now_time = datetime.datetime.now()  # 当前条数据记录的时间
            session.commit()
            # 增量更新评论
            await update_comment(bvid)
        # 如果不存在则创建视频并全量爬取

        else:
            await save_video(bvid)
            logging.info(f'{bvid}全量爬取')
            await get_all_comment(bvid)
        update_alert(bvid)
    except Exception as e:
        print(f'{bvid}更新失败{str(e)}')
        error_message = str(e)
    return error_message


def update_alert(bvid):
    session = DBUtil.get_thread_session()
    monitor_video = session.query(MonitoredVideo).filter_by(bvid=bvid).first()
    if monitor_video.comment_count == 0:
        return
    if monitor_video.alert_standard == 0:
        if (monitor_video.violence_count / monitor_video.comment_count) >= monitor_video.alert_rate:
            if session.query(Alert).filter_by(video_bvid=bvid).first() is None:
                task_id = session.query(MonitoringTask).filter(
                    MonitoringTask.monitored_videos.like(f'%{bvid}%')).first().id
                alert = Alert(alert_time=datetime.datetime.now(), video_bvid=bvid, alert_by=0, task_id=task_id,
                              is_active=True)
                session.add(alert)
    elif monitor_video.alert_standard == 1:
        if (monitor_video.sarcasm_count / monitor_video.comment_count) >= monitor_video.alert_rate:
            if session.query(Alert).filter_by(video_bvid=bvid).first() is not None:
                task_id = session.query(MonitoringTask).filter(
                    MonitoringTask.monitored_videos.like(f'%{bvid}%')).first().id
                alert = Alert(alert_time=datetime.datetime.now(), video_bvid=bvid, alert_by=1, task_id=task_id,
                              is_active=True)
                session.add(alert)
    else:
        if (monitor_video.sarcasm_count / monitor_video.comment_count) >= monitor_video.alert_rate:
            if session.query(Alert).filter_by(video_bvid=bvid).first() is not None:
                task_id = session.query(MonitoringTask).filter(
                    MonitoringTask.monitored_videos.like(f'%{bvid}%')).first().id
                alert = Alert(alert_time=datetime.datetime.now(), video_bvid=bvid, alert_by=2, task_id=task_id,
                              is_active=True)
                session.add(alert)
    session.commit()


# 将当前视频的数据存入历史数据库
def update_video_history_from_now(history_video):
    session = DBUtil.get_thread_session()
    monitoredVideoHistory = MonitoredVideoHistory(bvid=history_video.bvid, aid=history_video.aid,
                                                  video_name=history_video.video_name,
                                                  tid=history_video.tid,
                                                  tname=history_video.tname,
                                                  last_comment_time=history_video.last_comment_time,
                                                  comment_count=history_video.comment_count,
                                                  violence_count=history_video.violence_count,
                                                  sarcasm_count=history_video.sarcasm_count,
                                                  did_violence_count=history_video.did_violence_count,
                                                  alert_standard=history_video.alert_standard,
                                                  alert_rate=history_video.alert_rate,
                                                  pubdate=history_video.pubdate, views=history_video.views,
                                                  danmaku=history_video.danmaku,
                                                  favorite=history_video.favorite, coin=history_video.coin,
                                                  share=history_video.share, like=history_video.like,
                                                  dislike=history_video.dislike,
                                                  duration=history_video.duration, record_time=history_video.now_time)
    session.add(monitoredVideoHistory)
    session.commit()


